/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       gamestatemanager.cpp
 * Author:     karooolek
 * Created on: 2009-04-09
 *
 **********************************************************************************************************************/

#include "gamestatemanager.h"

namespace mGameEngine
{
namespace Game
{

GameStateManager::GameStateManager() :
    _gameStates(),
    _push(), _pop(0)
{
}

GameStateManager::~GameStateManager()
{
    while(!_gameStates.empty())
    {
        _gameStates.back()->end();
        _gameStates.pop_back();
    }
}

GameState *GameStateManager::getActiveGameState() const
{
    // no game states on stack
    if(_gameStates.empty())
    {
        return NULL;
    }

    return _gameStates.back();
}

void GameStateManager::setGameState(GameState *gameState)
{
    // no empty game states
    if(!gameState)
    {
        return;
    }

    popGameState();
    pushGameState(gameState);
}

void GameStateManager::pushGameState(GameState *gameState)
{
    // no empty game states
    if(!gameState)
    {
        return;
    }

    _push.push_back(gameState);
}

void GameStateManager::popGameState()
{
    // stack is empty
    if(_gameStates.empty())
    {
        return;
    }

    // pop game state from queue
    if(!_push.empty())
    {
        return _push.pop_back();
    }

    // queue pop
    ++_pop;
}

void GameStateManager::idle()
{
    // pop states
    while(!_gameStates.empty() && _pop)
    {
        _gameStates.back()->end();

        _gameStates.pop_back();
        --_pop;
    }

    // push states
    while(!_push.empty())
    {
        _gameStates.push_back(_push.front());
        _push.pop_front();

        _gameStates.back()->begin();
    }

    // no active game state
    if(_gameStates.empty())
    {
        return;
    }

    // loop active game state
    _gameStates.back()->idle();
}

void GameStateManager::draw() const
{
    // no game state
    if(_gameStates.empty())
    {
        return;
    }

    _gameStates.back()->draw();
}

}
}

